# Lock互斥锁
# 互斥锁就是进程的互相排斥，谁先抢到资源，谁就上锁改资源内容。同一时间只允许一个进程上一把锁。
# 互斥锁:能保证统一时刻只有一个线程执行，那个线程抢到这个互斥锁我们决定不了，但是能保证数据最终不会有问题
# 提示：加上互斥锁把多任务瞬间变成单任务，执行效率会下降。
# 主要方法：
# lock = Lock()，功能：创建锁对象
# lock.acquire()，功能：上锁，如果锁已经是上锁状态调用此函数会阻塞
# lock.release()，功能：解锁
# 还有一种上锁方法
# with lock

# global 在函数里修改全局变量关键字，global num，就代表调用全局的变量num，如果函数中无global关键字，优先读取局部变量，能读取全局变量，无法对全局变量重新赋值。nonlocal  修改上一级的变量
from threading import Thread, Lock
import time

# 定义全局变量：顶着头开始写，没有任何缩进，在py文件的任何位置都能调用
num = 0

# 创建互斥锁
lock = Lock()


# 循环给全局变量每次加上1
def sum1():
    # 上锁
    lock.acquire()
    global num
    for i in range(1000000):
        num += 1

    print("sum1:", num, time.ctime())
    # 释放锁
    lock.release()


def sum2():
    # 上锁
    lock.acquire()
    global num
    for i in range(1000000):
        num += 1

    print("sum2:", num, time.ctime())
    # 释放锁
    lock.release()


# with lock上锁
def sum3():
    number = 110  # 局部变量
    global num
    with lock:
        for i in range(1000000):
            num += 1
    # with lock与下面等价
    # lock.acquire()
    # try:
    #     for i in range(1000000):
    #         num+=1
    # finally:
    #     lock.release()
    print("sum3:", num, time.ctime())


if __name__ == '__main__':
    # 创建两个子线程
    thread1 = Thread(target=sum1)
    thread2 = Thread(target=sum2)
    thread3 = Thread(target=sum3)
    # 启动线程执行对应的任务
    thread1.start()
    thread2.start()
    thread3.start()
